//
//  YMPickerPhotosVC.swift
//  swift_review
//
//  Created by Andrew on 2024/11/24.
//

import UIKit
import PhotosUI
import Photos

struct Mediums {
    var type: String?
    var image: UIImage?
    var viderURL: URL?
}

// 全局宏，控制每行的照片数量
let itemsPerRow: Int = 5

class YMPickerPhotosVC: UIViewController {
    
    var collectionView: UICollectionView!
    var selectedMediums: [Mediums] = [] // 存储选中的照片
        
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        setupCollectionView()
        requestAuthorized()
    }
    
    func requestAuthorized() {
        // 请求相册权限
        PHPhotoLibrary.requestAuthorization { status in
            switch status {
            case .authorized:
                print("授权成功，可以访问相册")
                // 在这里执行访问相册的操作
            case .denied, .restricted:
                print("授权失败，无法访问相册")
                // 通常在这里你需要提醒用户开启权限
            case .notDetermined:
                print("用户尚未做出选择")
            case .limited:
                break
            @unknown default:
                break
            }
        }
    }
    
//    func photoShow() {
//        if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
//            if self.picker == nil {
//                self.picker = UIImagePickerController()
//                self.picker?.sourceType = UIImagePickerControllerSourceType.photoLibrary
//                self.picker?.delegate = self
//                //控制相册中显示视频和照片
//                self.picker?.mediaTypes = ["public.movie", "public.image"]
//                self.picker?.allowsEditing = false
//            }
//            self.present(picker!, animated: true, completion: nil)
//        } else {
//            print("读取图库失败")
//        }
//    }
    
    func setupCollectionView() {
        let layout = UICollectionViewFlowLayout()
        let spacing: CGFloat = 10
        let totalSpacing = CGFloat(itemsPerRow - 1) * spacing
        let itemWidth = (UIScreen.main.bounds.width - totalSpacing - 20) / CGFloat(itemsPerRow)
        layout.itemSize = CGSize(width: itemWidth, height: itemWidth)
        layout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
        layout.minimumInteritemSpacing = spacing
        layout.minimumLineSpacing = spacing
        
        collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.backgroundColor = .white
        
        collectionView.register(PhotoCell.self, forCellWithReuseIdentifier: "PhotoCell")
        
        view.addSubview(collectionView)
        view.addSubview(submitBtn)
        
        NSLayoutConstraint.activate([
            collectionView.topAnchor.constraint(equalTo: view.topAnchor),
            collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            
            submitBtn.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 80),
            submitBtn.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -80),
            submitBtn.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -80),
            submitBtn.heightAnchor.constraint(equalToConstant: 50)
        ])
        
    }
    
    private lazy var submitBtn: UIButton = {
        let view = UIButton(type: .custom)
        view.translatesAutoresizingMaskIntoConstraints = false
        view.setTitle("上传", for: .normal)
        view.backgroundColor = .blue
        view.setTitleColor(.white, for: .normal)
        view.addTarget(self, action: #selector(uploadMedias), for: .touchUpInside)
        return view
    }()
    
    func openPhotoPicker() {
        var configuration = PHPickerConfiguration()
        configuration.selectionLimit = 9 - selectedMediums.count // 剩余可选的照片数量
        configuration.filter = PHPickerFilter.any(of: [.images, .videos])
        
        let picker = PHPickerViewController(configuration: configuration)
        picker.delegate = self
        present(picker, animated: true)
    }
    
    func deleteImage(at index: Int) {
        selectedMediums.remove(at: index)
        collectionView.reloadData()
    }
    
    //上传照片
    @objc func uploadMedias() {
        var images: [UIImage] = [] // 图片数组
        var videos: [URL] = [] // 视频URL数组
        for model in selectedMediums {
            if model.type == "image" {
                images.append(model.image ?? UIImage())
            } else {
                if let videoURL = model.viderURL {
                    videos.append(videoURL)
                }
            }
        }
        
        FileUploader.uploadFiles(images: images, videos: videos, to: URL(string: "https://your-server.com/upload")!) { result in
            switch result {
            case .success(let success):
                print("上传成功:\(success)")
            case .failure(let failure):
                print("上传失败：\(failure)")
            }
        }
    }
}

extension YMPickerPhotosVC: UICollectionViewDelegate, UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        // 如果照片少于 9 张，显示多一个 "+" cell
        return selectedMediums.count < 9 ? selectedMediums.count + 1 : selectedMediums.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PhotoCell", for: indexPath) as! PhotoCell
        
        if indexPath.item < selectedMediums.count {
            // 显示照片
            let model = selectedMediums[indexPath.row]
            cell.imageView.image = model.image
            cell.imageView.contentMode = .scaleAspectFill
            cell.deleteButton.isHidden = false
            cell.deleteButton.tag = indexPath.item
            cell.deleteButton.addTarget(self, action: #selector(deleteButtonTapped(_:)), for: .touchUpInside)
        } else {
            // 显示 "+"
            cell.imageView.image = UIImage(systemName: "plus")
            cell.imageView.contentMode = .center
            cell.deleteButton.isHidden = true
        }
        
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        if indexPath.item == selectedMediums.count { // 点击 "+" cell 打开相册
            openPhotoPicker()
        }
    }
    
    @objc func deleteButtonTapped(_ sender: UIButton) {
        deleteImage(at: sender.tag)
    }
}

extension YMPickerPhotosVC: PHPickerViewControllerDelegate {
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        picker.dismiss(animated: true)
        
        for result in results {
            if result.itemProvider.canLoadObject(ofClass: UIImage.self) {
                result.itemProvider.loadObject(ofClass: UIImage.self) { [weak self] object, error in
                    if let image = object as? UIImage {
                        DispatchQueue.main.async {
                            var model = Mediums()
                            model.type = "image"
                            model.image = image
                            self?.selectedMediums.append(model)
                            self?.collectionView.reloadData()
                        }
                    }
                }
            } else {
                let itemProvider = result.itemProvider
                if itemProvider.hasItemConformingToTypeIdentifier(UTType.movie.identifier) {
                    itemProvider.loadFileRepresentation(forTypeIdentifier: UTType.movie.identifier) { [weak self] url, error in
                        guard let self = self, let url = url, error == nil else {
                            return
                        }
                        
                        // 转换 URL 为 AVURLAsset
                        let asset = AVURLAsset(url: url)
                        let thumbnail = self.getFirstGen(asset: asset)
                        var model = Mediums()
                        model.type = "image"
                        model.image = thumbnail
                        self.selectedMediums.append(model)
                        DispatchQueue.main.async {
                            self.collectionView.reloadData()
                        }
                    }
                }
                
            }
        }
    }
    
    //MARK: 获取第一帧当封面
    func getFirstGen(asset:AVURLAsset) -> UIImage? {
        if #available(iOS 18.0, *) {
            // iOS 18.0及以上版本，使用异步方法
            let assetGen = AVAssetImageGenerator(asset: asset)
            assetGen.appliesPreferredTrackTransform = true
            let time = CMTimeMake(value: 0, timescale: 600)
            var resultImage: UIImage?
            let semaphore = DispatchSemaphore(value: 0) // 用来同步异步回调
            assetGen.generateCGImageAsynchronously(for: time) { (cgImage, actualTime, error) in
                if let error = error {
                    print("错误: \(error.localizedDescription)")
                } else if let cgImage = cgImage {
                    resultImage = UIImage(cgImage: cgImage)
                }
                semaphore.signal() // 完成后释放信号量
            }
            semaphore.wait() // 等待异步完成
            return resultImage
        } else {
            let assetGen = AVAssetImageGenerator(asset: asset)
            assetGen.appliesPreferredTrackTransform = true
            let time = CMTimeMake(value: 0, timescale: 600)
            var actualTime:CMTime = .zero
            if let cgImage = try? assetGen.copyCGImage(at: time, actualTime: &actualTime) {
                let image = UIImage(cgImage: cgImage)
                return image
            }
            return nil
        }
    }
}

// 自定义 CollectionView Cell
class PhotoCell: UICollectionViewCell {
    let imageView: UIImageView = {
        let imageView = UIImageView()
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.clipsToBounds = true
        imageView.layer.cornerRadius = 8
        return imageView
    }()
    
    let deleteButton: UIButton = {
        let button = UIButton(type: .custom)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setImage(UIImage(systemName: "xmark.circle.fill"), for: .normal)
        button.tintColor = .red
        button.isHidden = true
        return button
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        contentView.addSubview(imageView)
        contentView.addSubview(deleteButton)
        
        NSLayoutConstraint.activate([
            imageView.topAnchor.constraint(equalTo: contentView.topAnchor),
            imageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
            imageView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
            imageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
            
            deleteButton.topAnchor.constraint(equalTo: contentView.topAnchor, constant: -5),
            deleteButton.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 5),
            deleteButton.widthAnchor.constraint(equalToConstant: 24),
            deleteButton.heightAnchor.constraint(equalToConstant: 24)
        ])
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension YMPickerPhotosVC {
    
    func getFirstThumb(from videoURL: URL, completion: @escaping (UIImage?) -> Void) {
        // 检查文件是否存在
        let fileManager = FileManager.default
        if !fileManager.fileExists(atPath: videoURL.path) {
            print("错误：文件不存在于路径 \(videoURL.path)")
            completion(nil)
            return
        }

        // 创建资产
        let asset = AVURLAsset(url: videoURL)
        let gen = AVAssetImageGenerator(asset: asset)
        gen.appliesPreferredTrackTransform = true
        let time = CMTimeMakeWithSeconds(0.0, preferredTimescale: 1)

        // 异步生成图像
        gen.generateCGImageAsynchronously(for: time) { (image, actualTime, error) in
            if let error = error {
                print("错误：\(error.localizedDescription)")
                completion(nil)
                return
            }

            if let image = image {
                let uiImage = UIImage(cgImage: image)
                completion(uiImage)
            } else {
                print("警告：无法生成图像")
                completion(nil)
            }
        }
    }
    
    func getFirstFrame(from videoURL: URL, completion: @escaping (UIImage?) -> Void) {
        // 使用 AVURLAsset 替代 AVAsset
        let asset = AVURLAsset(url: videoURL)
        
        // 使用 loadTracks(withMediaType:) 来替代 tracks(withMediaType:)
        asset.loadTracks(withMediaType: .video) { tracks, error in
            if let error = error {
                print("Error loading tracks: \(error)")
                completion(nil)
                return
            }
            
            guard let videoTrack = tracks?.first else {
                print("No video track found")
                completion(nil)
                return
            }
            
            let assetReader: AVAssetReader
            do {
                assetReader = try AVAssetReader(asset: asset)
            } catch {
                print("Error creating asset reader: \(error)")
                completion(nil)
                return
            }
            
            let videoSettings: [String: Any] = [
                AVVideoCodecKey: AVVideoCodecType.jpeg
            ]
            
            let assetReaderOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: videoSettings)
            assetReader.add(assetReaderOutput)
            assetReader.startReading()
            
            if let sampleBuffer = assetReaderOutput.copyNextSampleBuffer(), let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) {
                let ciImage = CIImage(cvImageBuffer: imageBuffer)
                let context = CIContext(options: nil)
                
                if let cgImage = context.createCGImage(ciImage, from: ciImage.extent) {
                    let image = UIImage(cgImage: cgImage)
                    completion(image)
                } else {
                    completion(nil)
                }
            } else {
                completion(nil)
            }
        }
    }
}
